﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ZLWeb.WebApiConfigration
{
    /// <summary>
    ///     读取通用WebService配置并缓存
    /// </summary>
    public static class GeneralWebServiceConfig
    {
        #region 初始化

        static GeneralWebServiceConfig()
        {
            rootElement = XElement.Load(AppDomain.CurrentDomain.BaseDirectory + "\\FuncData.xml");
            _definedFunctions = new Dictionary<string, DefinedFunction>();
        }

        //根文件
        private static readonly XElement rootElement;
        private static string _kvName;
        private static string _kvVer;
        private static Dictionary<string, DefinedFunction> _definedFunctions;

        #endregion

        #region 版本校验

        public static string KvName
        {
            get
            {
                if (!string.IsNullOrEmpty(_kvName)) return _kvName;
                var orDefault = rootElement.Elements("DefinedFunctions")
                    .FirstOrDefault();
                if (orDefault == null) return _kvName;
                var firstOrDefault = orDefault
                    .Attributes("SetName")
                    .FirstOrDefault();
                if (firstOrDefault != null)
                    _kvName =
                        firstOrDefault
                            .Value;
                return _kvName;
            }
        }

        public static string KvVer
        {
            get
            {
                if (!string.IsNullOrEmpty(_kvVer)) return _kvVer;
                var orDefault = rootElement.Elements("DefinedFunctions")
                    .FirstOrDefault();
                if (orDefault == null) return _kvVer;
                var firstOrDefault = orDefault
                    .Attributes("Version")
                    .FirstOrDefault();
                if (firstOrDefault != null)
                    _kvVer =
                        firstOrDefault
                            .Value;
                return _kvVer;
            }
        }

        #endregion

        #region 管道配置

        public static Dictionary<string, DefinedFunction> DefinedFunctions
        {
            get
            {
                if (_definedFunctions.Any()) return _definedFunctions;
                _definedFunctions = GetDefinedFunctions();
                return _definedFunctions;
            }
        }

        private static Dictionary<string, DefinedFunction> GetDefinedFunctions()
        {
            var result = new Dictionary<string, DefinedFunction>();

            foreach (var definedFunction in rootElement.Elements("DefinedFunctions").Elements("DefinedFunction"))
            {
                //组装标量参数
                var tmpScalarPars =
                    definedFunction.Elements("DefinedScalarPars").Elements("DefinedScalarPar")
                        .ToDictionary(
                            definedScalarPar =>
                                definedScalarPar.Attributes("ScalarParName").FirstOrDefault().Value,
                            definedScalarPar =>
                            {
                                var attribute = definedScalarPar.Attributes("Type").FirstOrDefault().Value;
                                var firstOrDefault = definedScalarPar.Attributes("Output").FirstOrDefault().Value;
                                return attribute != null
                                    ? new ScalarParam
                                    {
                                        ParamName =
                                            definedScalarPar.Attributes("ScalarParName")
                                                .FirstOrDefault()
                                                .Value,
                                        OutPut =
                                            firstOrDefault != null && (firstOrDefault.ToString()) ==
                                            "1",
                                        ParamDbType =
                                            attribute.ToString()
                                    }
                                    : null;
                            });

                //组装数据表参数
                var tmpRecondPars =
                    new Dictionary<string, RecondParam>();

                foreach (
                    var definedRecordPar in definedFunction.Elements("DefinedRecordPars").Elements("DefinedRecordPar"))
                {
                    //表的列组装
                    var tmpRecondFilds = definedRecordPar.Elements("Fields").Elements("Field")
                        .ToDictionary(
                            recondFild => recondFild.Attributes("FieldName").FirstOrDefault().Value,
                            recondFild =>
                            {
                                var firstOrDefault = recondFild.Attributes("Type").FirstOrDefault().Value;
                                return firstOrDefault != null
                                    ? new RecondFild
                                    {
                                        FildName = recondFild.Attributes("FieldName").FirstOrDefault().Value,
                                        FildDbType = firstOrDefault.ToString()
                                        //Nullable = recondFild.Attributes("Type").FirstOrDefault().ToString() == "1"
                                    }
                                    : new RecondFild
                                    {
                                        FildName = recondFild.Attributes("FieldName").FirstOrDefault().Value
                                        //Nullable = recondFild.Attributes("Type").FirstOrDefault().ToString() == "1"
                                    };
                            });
                    var xAttribute = definedRecordPar.Attributes("NeedAttachSN").FirstOrDefault().Value;
                    var orDefault = definedRecordPar.Attributes("Output").FirstOrDefault().Value;
                    var tmpRecondParam = new RecondParam
                    {
                        RecondFilds = tmpRecondFilds,
                        NeedAttachSN = xAttribute != null && xAttribute == "1",
                        OutPut = orDefault != null && orDefault == "1",
                        ParamTableName = definedRecordPar.Attributes("RecordParName").FirstOrDefault().Value
                    };


                    tmpRecondPars.Add(definedRecordPar.Attributes("RecordParName").FirstOrDefault().Value,
                        tmpRecondParam);
                }


                result.Add(definedFunction.Attributes("FunctionName").FirstOrDefault().Value,
                    new DefinedFunction
                    {
                        StoreProcName = definedFunction.Attributes("StoreProcName").FirstOrDefault().Value,
                        FunctionName = definedFunction.Attributes("FunctionName").FirstOrDefault().Value,
                        RecondPars = tmpRecondPars,
                        ScalarPars = tmpScalarPars
                    });
            }


            return result;
        }

        #endregion
    }
}